package com.iflytek.aiui.voiceclone;

import java.io.File;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;

import com.alibaba.fastjson.JSONObject;
import com.iflytek.aiui.voiceclone.util.HttpUtil;

/**
 * AIUI 声音复刻资源管理demo
 *
 */
@SuppressWarnings("all")
public class VoiceCloneSgenDemo {

    // 请求地址
    private static final String BASE_URL = "http://aiui.xf-yun.com/v2/aiint/voice-clone";
    private static final String REG_PATH = "/sgen/reg";
    private static final String DEL_PATH = "/sgen/del";

    // 应用配置
    private static final String APPID = "";        
    private static final String APIKEY = "";
    private static final String APISECRET= "";
    // 设备sn号
    private static final String SN= "";
    // 音频文件路径
    private static final String FILE_PATH = "";

    public static void main(String[] args) throws Exception {
        // 声音复刻
        String regResStr = sgenReg(APPID, SN, FILE_PATH, APIKEY, APISECRET);
        JSONObject regRes = JSONObject.parseObject(regResStr);
        if (regRes.getIntValue("code") != 0) {
            System.out.println("sgenReg fail:" + regResStr);
        }
        String resId = regRes.getJSONObject("data").getString("res_id");
        System.out.println("voice clone success, sgenReg res_id:" + resId);

        // 复刻资源删除
//        String resId = "";
//        String delResStr = sgenDel(APPID, SN, resId, APIKEY, APISECRET);
//        JSONObject delRes = JSONObject.parseObject(delResStr);
//        if (delRes.getIntValue("code") != 0) {
//            System.out.println("sgenDel fail:" + delResStr);
//            return;
//        }
//        System.out.println("voice clone res delete success");
    }

    private static String sgenReg(String appid, String sn, String filePath, String apiKey, String apiSecret) throws Exception {
        String url = getAuthUrl(BASE_URL + REG_PATH, "POST", apiKey, apiSecret);
        MultipartEntityBuilder builder  = MultipartEntityBuilder.create();
        builder.addTextBody("appid", appid);
        builder.addTextBody("sn", sn);
        builder.addPart("data", new FileBody(new File(filePath)));
        return HttpUtil.postWithEntity(url, builder.build());
    }

    private static String sgenDel(String appid, String sn, String resId, String apiKey, String apiSecret) throws Exception {
        String url = getAuthUrl(BASE_URL + DEL_PATH, "DELETE", apiKey, apiSecret);
        JSONObject reqBody = new JSONObject();
        reqBody.put("appid", appid);
        reqBody.put("sn", sn);
        reqBody.put("res_id", resId);
        return HttpUtil.delete(url, reqBody);
    }

    // 生成带授权参数的请求url
    private static String getAuthUrl(String url, String method, String apiKey, String apiSecret) throws Exception {
        URI uri = URI.create(url);
        String host = uri.getHost();
        String path = uri.getPath();
        // 获取当前GMT时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接 host date request-line
        String headerLine = "host: " + host + "\n" + "date: " + date + "\n" + method + " " + path + " HTTP/1.1";
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);

        byte[] hexDigits = mac.doFinal(headerLine.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // 生成authorization
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"",
                apiKey, "hmac-sha256", "host date request-line", sha);
        String authorizationBase64 = Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8));

        // 生成鉴权URL
        return String.format("%s?authorization=%s&date=%s&host=%s",
                url,
                URLEncoder.encode(authorizationBase64, "UTF-8"),
                URLEncoder.encode(date, "UTF-8"),
                URLEncoder.encode(host, "UTF-8"));
    }
}